﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
using BLL.Store;
using System.Transactions;
using System.Net.Mail;
using System.Text;
using System.IO;
using Extensions;
using System.Collections.Generic;
using System.ComponentModel;
namespace DAL
{
    /// <summary>
    /// Summary description for Order
    /// </summary>
    /// 
    
    public partial class Order
    {
        private ShoppingCart _shoppingCart;
        public object GetOrderItems(int orderId)
        {
            using (EShopDBDataContext db = new EShopDBDataContext())
            {
                var result = from orderItems in db.OrderItems
                             join product in db.Products on orderItems.ProductID equals product.ProductId
                             where orderItems.OrderID == orderId
                             select new
                             {
                                 ProductTitle = product.Title,
                                 ProductPrice = product.Price,
                                 ProductId = product.ProductId
                             };
                return result.ToList();
            }
        }
        public object GetOrders()
        {
            using (EShopDBDataContext db = new EShopDBDataContext())
            {
                var result = from order in db.Orders
                             orderby order.AddedDate descending
                             select new 
                             {
                                 OrderID = order.OrderID,
                                 OrderDate = order.AddedDate,
                                 UserName = order.AddedBy,
                                 ShippingCity = order.ShippingCity,
                                 ShippingStreet = order.ShippingStreet,
                                 ShippingFirstName = order.ShippingFirstName,
                                 ShippingLastName = order.ShippingLastName,
                                 SubTotal = order.SubTotal,
                                 ShippingCountry = order.ShippingCountry,
                                 CustomerEmail = order.CustomerEmail,
                                 CustomerPhone = order.CustomerPhone,
                                 ItemsCount = (from orderItem in db.OrderItems
                                               where orderItem.OrderID == order.OrderID
                                               select orderItem).Count()
                             };
                return result.ToList();
            }
        }
        private void SendOrderConfirmationEmail()
        {
            MailAddress toAddress = new MailAddress(this.CustomerEmail);
            MailAddress fromAddress = new MailAddress(ConfigurationManager.AppSettings["Order_Email_Adress"],
                ConfigurationManager.AppSettings["Order_Email_SenderName"], Encoding.UTF8);
            MailMessage message = new MailMessage(fromAddress, toAddress);
            message.BodyEncoding = Encoding.UTF8;
            message.SubjectEncoding = Encoding.UTF8;
            message.Subject = ConfigurationManager.AppSettings["Order_Email_Subject"];
            message.Body = GetOrderConfirmationMessageBody();
            System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
            client.Send(message);
        }

        private void SendPlaceOrderAdminEmail()
        {
            MailAddress ma = new MailAddress(ConfigurationManager.AppSettings["Order_Email_Adress"],
                ConfigurationManager.AppSettings["Order_Email_SenderName"], Encoding.UTF8);
            MailMessage message = new MailMessage(ma, ma);
            message.BodyEncoding = Encoding.UTF8;
            message.SubjectEncoding = Encoding.UTF8;
            message.Subject = ConfigurationManager.AppSettings["Order_Email_Subject"];
            message.Body = GetOrderAdminMessageBody();
            System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
            client.Send(message);
        }

        private string GetOrderAdminMessageBody()
        {
            string path = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["Order_Email_AdminNotification"]);
            string body = GetFileText(path);
            StringBuilder orderDetails = new StringBuilder();
            foreach (ShoppingCartItem item in _shoppingCart.Items)
            {
                orderDetails.AppendLine(string.Format("{0} ({1}) - {2}", item.Title.Trim(), item.Quantity, (item.UnitPrice * item.Quantity).ToMoneyString()));
            }
            body = body.Replace("<%user_name%>", string.Format("{0} {1}", ShippingFirstName, ShippingLastName)).Replace("<%shipping%>", Shipping.ToMoneyString());
            body = body.Replace("<%order_id%>", OrderID.ToString()).Replace("<%amount%>", (_shoppingCart.Total + Shipping).ToMoneyString());
            body = body.Replace("<%order%>", orderDetails.ToString()).Replace("<%phone%>", CustomerPhone);
            body = body.Replace("<%order_id%>", OrderID.ToString()).Replace("<%email%>", CustomerEmail);
            body = body.Replace("<%address%>", string.Format("{0}, {1}, {2}", ShippingState, ShippingCity, ShippingStreet));
            return body;
        }

        private string GetOrderConfirmationMessageBody()
        {
            string path = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["Order_Email_BodyTemplatePath"]);
            string body = GetFileText(path);
            StringBuilder orderDetails = new StringBuilder();
            foreach (ShoppingCartItem item in _shoppingCart.Items)
            {
                orderDetails.AppendLine(string.Format("{0} ({1}) - {2}", item.Title.Trim(), item.Quantity, (item.UnitPrice * item.Quantity).ToMoneyString()));
            }
            body = body.Replace("<%user_name%>", string.Format("{0} {1}", ShippingFirstName, ShippingLastName)).Replace("<%shipping%>", Shipping.ToMoneyString());
            body = body.Replace("<%order_id%>", OrderID.ToString()).Replace("<%amount%>", (_shoppingCart.Total + Shipping).ToMoneyString());
            body = body.Replace("<%order%>", orderDetails.ToString());
            body = body.Replace("<%order_id%>", OrderID.ToString());
            return body;
        }

        private static string GetFileText(string path)
        {
            string body;
            using (FileStream s = File.OpenRead(path))
            {
                TextReader tr = new StreamReader(s);
                body = tr.ReadToEnd();
            }
            return body;
        }

        public void PlaceOrder(ShoppingCart shoppingCart)
        {
            if (shoppingCart == null)
                throw new InvalidOperationException("Shopping cart is null. Order cannot be placed");
            if (shoppingCart.Items.Count == 0)
                throw new InvalidOperationException("Shopping cart is empty. Order cannot be placed");
            _shoppingCart = shoppingCart;
            using (EShopDBDataContext db = new EShopDBDataContext())
            {
                using (TransactionScope scope = new TransactionScope())
                {
                    string userName = string.IsNullOrEmpty(HttpContext.Current.User.Identity.Name) ? "" : HttpContext.Current.User.Identity.Name;
                    // insert the master order
                    db.Orders.InsertOnSubmit(this);
                    // insert the child order items
                    foreach (ShoppingCartItem item in shoppingCart.Items)
                    {
                        OrderItem orderItem = new OrderItem
                        {
                            AddedDate = DateTime.Now,
                            AddedBy = userName,
                            ProductID = item.ID,
                            Title = item.Title,
                            UnitPrice = item.UnitPrice,
                            Quantity = item.Quantity
                        };
                        this.OrderItems.Add(orderItem);
                    }
                    db.SubmitChanges();
                    scope.Complete();
                }
            }
            SendOrderConfirmationEmail();
            SendPlaceOrderAdminEmail();
        }
    }
}